제너릭

✒️ 2025-05-26 18:18 내용 수정


참고 자료 : Inpa dev's 자바 제네릭(Generics) 개념 & 문법 정복하기, Inpa dev's 자바 제네릭의 공변성 & 와일드카드 완벽 이해

클래스나 메서드에서 사용할 내부 데이터 타입을 객체 선언 시 외부에서 미리 지정하여 관리하는 것

제너릭 타입 제한

// Number의 하위 클래스만 올 수 있음
// 본인 ~ Number까지
class ExamList<T extends Number> {}

// Integer와 그의 상위 클래스만 올 수 있음
// Integer ~ 본인까지
class ExamList<T super Integer> {}

1. 제너릭 클래스

클래스 정의 시 멤버의 데이터 타입을 미리 지정하지 않고 인스턴스 생성 시 타입을 지정할 수 있는 클래스

public class 클래스이름<T> {
	T data;
}

public interface 인터페이스이름<T> {
	T data;
}
타입변수 의미
<T> Type
* 객체 선언 시에는 T 위치에 Wrapper 클래스로 작성
(Wrapper 클래스)
<E> Element
<K> Key
<N> Number
<V> Value
class ClassName<T, M> {}
클래스이름<T> 인스턴스이름 = new 클래스이름<T>();

클래스이름<T> 인스턴스이름 = new 클래스이름<>();
// 제너릭 클래스를 생성할 때 타입 변수 자리에 실제 Wrapper 타입 쓰기
MyArray<Integer> myArr = new MyArray<Integer>(); 
// 클래스 내부 타입들은 정수형으로 변환!
class MyArray<T> { // T 타입 변수
	T element;
	void setElement(T element) {
	}
	T getElement() {
		return element;
	}
}

// 인터페이스를 구현하는 경우에도 extends
interface Check {}
class ExamList<T extends Check> {}

// 클래스와 인터페이스 동시 상속, 구현한다면 & 사용
class ExamList<T extends Exam & Check> {}

2. 제너릭 메서드

메서드 선언수에 타입 변수를 사용한 메서드

접근제어자 기타제어자 <T> 리턴타입 메서드이름() {}
public <T> T test(T data) {}
public static <T> void test() {}
public static <T, V> void test(Object<T,V> obj1, Object<T,V> obj2) {}

ClassName.test(obj1, obj2); // 호출 시 제네릭 생략

3. 와일드카드

<?> //타입 변수에 모든 타입 사용 가능
<? extends T> // 하위 타입이 T까지인 경우만
<? super T> // 상위 타입이 T인 경우만

제너릭 vs 와일드카드

항목 제네릭 (Generic) 와일드카드 (Wildcard)
정의 위치 클래스나 메서드 선언부에서 타입 매개변수로 정의 (<T>) 타입 사용 시에만 사용 (?, ? extends T, ? super T)
타입 명시 여부 명시적으로 타입을 지정하여 사용
T는 기본적으로 Object 타입
불특정한 타입을 나타내며, 구체적인 타입을 알 필요 없음
사용 목적 특정 타입에 대해 구체적인 동작을 정의할 때 사용 다양한 타입을 유연하게 처리할 때 사용
읽기/쓰기 가능성 읽기 및 쓰기 모두 가능 제한적
? extends T읽기 전용
? super T쓰기 전용
타입 추론 컴파일러가 타입을 정확히 추론 컴파일러가 타입을 일부만 추론하거나 제한적 추론
예시 <T> void add(T item) void add(List<? extends Number> list)